package com.aji.alluser.controller;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.aji.allcommon.result.Result;
import com.aji.alluser.domain.RoleUser;
import com.aji.alluser.domain.User;
import com.aji.alluser.domain.dto.UserDto;
import com.aji.alluser.domain.vo.UserInfo;
import com.aji.alluser.domain.vo.UserVO;
import com.aji.alluser.service.LoginService;
import com.aji.alluser.service.RoleService;
import com.aji.alluser.service.RoleUserService;
import com.aji.alluser.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/user")
@Api(tags = "用户管理")
@RequiredArgsConstructor
public class UserController{
    @Autowired
    UserService userService;
    @Autowired
    RoleUserService roleUserService;
    @Autowired
    LoginService loginService;

    private final RoleService roleService;

    @ApiOperation("查询 分页 条件")
//    @PreAuthorize("hasAuthority('admin')")
    @GetMapping("/{page}/{pageSize}")
    public Result pageList(@PathVariable Integer page, @PathVariable Integer pageSize, String name, String username, String phone, String beginCreateTime, String endCreateTime, String school,Integer status){
        Page<User> rowPage = new Page<>(page, pageSize);

        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
                .select(User::getId, User::getUsername, User::getName,
                        User::getPhone, User::getSchool, User::getStatus,
                        User::getCreateTime, User::getEmail)
                .ne(User::getId, 1) // 不显示管理员
                .like(StringUtils.hasText(username), User::getUsername, username)
                .like(StringUtils.hasText(name), User::getName, name)
                .like(StringUtils.hasText(phone), User::getPhone, phone)
                .like(StringUtils.hasText(school), User::getSchool, school)
                .eq(status != null, User::getStatus, status)
                .ge(StringUtils.hasText(beginCreateTime), User::getCreateTime, beginCreateTime)
                .le(StringUtils.hasText(endCreateTime), User::getCreateTime, endCreateTime)
                .orderByDesc(User::getCreateTime);

        Page<User> userPage = (Page<User>) userService.page(rowPage, wrapper);

        List<UserVO> userVOList = userPage.getRecords().stream()
                .map(u -> {
                    // 调用角色查询服务
                    List<Integer> roleList = roleUserService.getRoleById(u.getId());
                    return new UserVO(
                            u.getId(),
                            u.getUsername(),
                            u.getName(),
                            u.getPhone(),
                            u.getSchool(),
                            u.getStatus(),
                            roleList,
                            u.getCreateTime(),
                            u.getEmail()
                    );
                }).collect(Collectors.toList());

        Page<UserVO> voPage = new Page<>(page, pageSize, userPage.getTotal());
        voPage.setRecords(userVOList);

        return Result.success(voPage);
    }

    @ApiOperation("增加 需要忽略id")
    @PostMapping()
    public Result save(@RequestBody UserDto userDto){
        long userId = IdWorker.getId();
        String passwordRaw = userDto.getPassword();
        // 定义密码规则正则表达式 长度8到10，, 包含大小写数字和特殊字符
        String regex = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=!])(?=\\S+$).{6,20}$";
        // 创建 Pattern 对象
        Pattern pattern = Pattern.compile(regex);
        // 创建 Matcher 对象
        Matcher matcher = pattern.matcher(passwordRaw);
        if(!matcher.matches()){return Result.error("密码长度6到20，, 包含大小写数字和特殊字符");}
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String password = passwordEncoder.encode(userDto.getPassword());
        userDto.setPassword(password);
        User user = new User();
        BeanUtil.copyProperties(userDto, user);
        user.setId(userId);
        user.setCreateTime(LocalDateTime.now());
        userService.save(user);

        UserInfo userInfo = loginService.userInfo(userDto.getToken());

        RoleUser roleUser = RoleUser.builder()
                .operator(userInfo.getName()).build();

        userDto.getRoleUserList().forEach(role -> {
            roleUser.setUserId(userId);
            roleUser.setRoleId(role);
            roleUserService.save(roleUser);
        });
        return Result.success();
    }

    @ApiOperation("删除")
    @DeleteMapping("/{ids}")
//    @PreAuthorize("hasAuthority('admin')")
    public Result delete(@PathVariable List<String> ids){
        if(ids.contains(1)){
            return Result.error("拒绝访问");
        }
        userService.removeByIds(ids);
        LambdaQueryWrapper<RoleUser>roleUserLambdaQueryWrapper =new LambdaQueryWrapper<RoleUser>()
                .select().in(RoleUser::getUserId,ids);
        roleUserService.remove(roleUserLambdaQueryWrapper);
        return Result.success();
    }

    @ApiOperation("修改")
//    @PreAuthorize("hasAuthority('admin')")
    @PutMapping()
    public Result updateById(@RequestBody UserDto entity) {
        // 禁止修改系统管理员账户
        if (Objects.equals(entity.getId(), 1L)) {
            return Result.error("禁止修改系统管理员账户");
        }

        // 获取当前登录用户信息（可选）
        UserInfo userInfo = StringUtils.hasText(entity.getToken())
                ? loginService.userInfo(entity.getToken())
                : null;

        // 查询数据库中当前用户
        User user = userService.getById(entity.getId());
        if (user == null) {
            return Result.error("用户不存在");
        }

        // 忽略空字符串的属性复制，防止覆盖数据库中已有值
        CopyOptions options = CopyOptions.create()
                .ignoreNullValue()
                .setFieldValueEditor((fieldName, value) -> {
                    if (value instanceof String && ((String) value).trim().isEmpty()) {
                        return null;
                    }
                    return value;
                });

        // 先复制除密码外的属性
        BeanUtil.copyProperties(entity, user, options);

        // 只要传了密码就加密更新
        String passwordRaw = entity.getPassword();
        if (StringUtils.hasText(passwordRaw)) {
            // 检查密码复杂度
            String regex = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=!])(?=\\S+$).{8,10}$";
            if (!Pattern.matches(regex, passwordRaw)) {
                return Result.error("密码长度需为8到10位，且包含大小写字母、数字和特殊字符");
            }

            // 加密并设置
            BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
            user.setPassword(passwordEncoder.encode(passwordRaw));
        }

        // 更新用户
        userService.updateById(user);

        // 更新角色信息
        if (entity.getRoleUserList() != null) {
            // 删除旧的角色关联
            roleUserService.remove(
                    new LambdaQueryWrapper<RoleUser>().eq(RoleUser::getUserId, entity.getId())
            );

            // 插入新的角色关联
            if (!entity.getRoleUserList().isEmpty()) {
                List<RoleUser> newRoleList = entity.getRoleUserList().stream()
                        .map(roleId -> RoleUser.builder()
                                .roleId(roleId)
                                .userId(entity.getId())
                                .operator(userInfo != null ? userInfo.getName() : "system")
                                .build())
                        .collect(Collectors.toList());
                roleUserService.saveBatch(newRoleList);
            }
        }

        return Result.success();
    }





    @ApiOperation("查询 根据id")
//    @PreAuthorize("hasAuthority('admin')")
    @GetMapping("/{id}")
    public Result getById(@PathVariable String id){
        Long userId = Long.valueOf(id);
        User user = userService.getById(userId);
        if (user == null) {
            return Result.error("未找到该用户");
        }

        List<Integer> roleUserList = roleUserService.getRoleById(user.getId());

        UserVO userVO = new UserVO(
                user.getId(),
                user.getUsername(),
                user.getName(),
                user.getPhone(),
                user.getSchool(),
                user.getStatus(),
                roleUserList,
                user.getCreateTime(),
                user.getEmail()
        );

        return Result.success(userVO);
    }

    @ApiOperation("查询 全部")
    //    @PreAuthorize("hasAuthority('admin')")
    @GetMapping("/list")
    public Result list(){
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        List<User> users = userService.list(wrapper);
        List<UserVO> userVOList = users.stream()
                .map(u -> {
                    List<Integer> roleUserList = roleUserService.getRoleById(u.getId());
                    return new UserVO(u.getId(),u.getUsername(),
                            u.getName(), u.getPhone(), u.getSchool(),
                            u.getStatus(), roleUserList, u.getCreateTime(), u.getEmail()
                    );
                }).collect(Collectors.toList());

        return Result.success(userVOList);
    }

}
